package com.common.aop;

import com.common.inter.LogInter;
import com.common.util.SecreUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.ui.Model;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * Created by dell on 2016/11/17.
 */
@Aspect
@Component
public class WebLogAspect {

    private static Logger logger = LoggerFactory.getLogger(WebLogAspect.class);

    @Autowired(required = false)
    private LogInter logInter;

    ThreadLocal<String> logid = new ThreadLocal<>();
    ThreadLocal<Long> startTime = new ThreadLocal<>();

    @Pointcut("execution(public * com..controller..*.*(..))")
    public void webLog(){}

    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        // 接收到请求，记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        ipLimit(request);
        Object objs[] = joinPoint.getArgs();
        for(Object obj:objs){
            if(obj instanceof Model) {
                StringBuffer sb = new StringBuffer(request.getScheme());
                sb.append("://");sb.append(request.getServerName());
                sb.append(":");sb.append(request.getServerPort());
                sb.append(request.getContextPath());//sb.append("/");
                ((Model) obj).addAttribute("url",sb.toString());
            }
        }
        // 记录下请求内容
        startTime.set(System.currentTimeMillis());
        logger.info("URL : " + request.getRequestURL().toString());
        logger.info("HTTP_METHOD : " + request.getMethod());
        logger.info("IP : " + request.getRemoteAddr());
        logger.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        logger.info("ARGS : " + Arrays.toString(joinPoint.getArgs()));
        String url=request.getRequestURL().toString();
        logid.set(UUID.randomUUID().toString());
        String ip=request.getRemoteAddr().toString();
        String hmethod=request.getMethod();
        String classMethod=joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
        String args=Arrays.toString(joinPoint.getArgs());
        logInter.addStart(logid.get(),url,hmethod,ip,classMethod,args,new Date(),SecreUtil.getUserId(),SecreUtil.getUserName());
        SecreUtil.putSessionValue("logId",logid.get());
        logger.info("logId :   "+SecreUtil.getSessionValue("logId"));
        logger.info("userId:   "+SecreUtil.getUserId());
        logger.info("userName:   "+SecreUtil.getUserName());
    }
    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void doAfterReturning(Object ret) throws Throwable {
        String res=ret==null?"":ret.toString();
        // 处理完请求，返回内容
        logger.info("RESPONSE : " + ret);
        logger.info("SPEND TIME : " + (System.currentTimeMillis() - startTime.get()));
        logInter.addEnd(logid.get(),res,""+(System.currentTimeMillis() - startTime.get()));
    }

    public void ipLimit(HttpServletRequest request){
        Map<String,Boolean> ips=new HashMap<>();
//        ips.put("127.0.0.1",true);
        String ip=getIpAddr(request);
        if(ips.get(ip)!=null){
            //当前ip在黑名单
            throw new RuntimeException("你已经被列入了黑名单");
        }else{

        }
    }

    //获得客户端真实IP地址的方法
    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("PRoxy-Client-IP");
        }
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}
